`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    16:33:04 12/21/2019 
// Design Name: 
// Module Name:    L2S 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module L2S(
    input wire clk,
    input wire rst,
    input wire start,
    input wire[DATA_BITS-1:0] P_Data,
    output wire sclk,
    output wire sout,
    output wire sclrn,
    output reg sen
    );
    
    parameter DATA_BITS = 16;
    parameter DIR = 0; // 0-left, 1-right
    
    reg[1:0] start_state;
    initial start_state = 2'b00;
    always @(posedge clk) start_state = {start_state[0], start};
    
    reg[1:0] S;
    initial S = 2'b00;
    wire[DATA_BITS:0] D, Q;
    assign D = DIR ? {1'b0, P_Data} : {P_Data, 1'b0};
    ShiftReg #(.DATA_BITS(DATA_BITS + 1))
             sr(.clk(clk), .S(S), .SL(1'b1), .SR(1'b1), .D(D), .Q(Q));
             
    wire finish;
    assign finish = DIR ? &Q[DATA_BITS:1] : &Q[DATA_BITS-1:0];
    assign sout = DIR ? Q[0] : Q[DATA_BITS];
    always @(posedge clk) begin
        if (rst) begin
            sen = 1'b1;
            S = DIR ? 2'b01 : 2'b10;
        end else begin
            if (start_state == 2'b01) begin
                sen = 1'b0;
                S = 2'b11;
            end else if (!finish) begin
                sen = 1'b0;
                S = DIR ? 2'b01 : 2'b10;
            end else begin
                sen = 1'b1;
                S = 2'b00;
            end
        end
    end

    assign sclk = finish | clk;
    assign sclrn = 1;

endmodule

